# -*- coding: utf-8 -*-
import requests
import re
import time
import xlwt

def main():
    # 请求头，模拟浏览器访问
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }

    # 基础URL
    base_url = 'https://book.douban.com/top250'

    print('开始爬取豆瓣读书Top250完整榜单...')

    all_books_data = []  # 存储所有书籍数据
    total_books = 0      # 统计总书籍数量

    # 循环爬取10页数据（每页25本，共250本）
    for page in range(10):
        start = page * 25
        if start == 0:
            url = base_url
        else:
            url = f'{base_url}?start={start}'

        print(f'\n正在爬取第 {page + 1} 页 (URL: {url})...')

        try:
            # 发送GET请求
            response = requests.get(url, headers=headers, timeout=10)
            response.encoding = 'utf-8'

            if response.status_code == 200:
                # 解析当前页面的书籍数据
                page_books_data = parse_books(response.text, page + 1)
                all_books_data.extend(page_books_data)
                total_books += len(page_books_data)

                print(f'第 {page + 1} 页爬取完成，获得 {len(page_books_data)} 本书')

                # 延时避免请求过快
                time.sleep(1)
            else:
                print(f'第 {page + 1} 页请求失败，状态码: {response.status_code}')
                break

        except Exception as e:
            print(f'第 {page + 1} 页爬取失败: {e}')
            break

    print(f'\n爬取完成！总共获得 {total_books} 本书')

    # 保存数据到Excel
    save_to_excel(all_books_data)

def parse_books(html_content, page_num=1):
    print(f'\n第 {page_num} 页：开始解析书籍数据...')

    # 书籍列表的正则表达式
    book_pattern = r'<tr class="item">.*?</tr>'
    books = re.findall(book_pattern, html_content, re.DOTALL)

    print(f'第 {page_num} 页找到 {len(books)} 本书')

    books_data = []
    for i, book_html in enumerate(books, 1):
        # 计算全局书籍编号
        global_book_num = (page_num - 1) * 25 + i

        # 提取书名
        title_match = re.search(r'<a href="[^"]*".*?title="([^"]*)"', book_html)
        title = title_match.group(1) if title_match else '未找到书名'

        # 提取作者和出版社信息
        info_match = re.search(r'<p class="pl">(.*?)</p>', book_html)
        info = info_match.group(1) if info_match else '未找到出版信息'

        # 提取评分
        rating_match = re.search(r'<span class="rating_nums">([^<]*)</span>', book_html)
        rating = rating_match.group(1) if rating_match else '未找到评分'

        # 提取评价人数
        rating_count_match = re.search(r'<span class="pl">\(\s*(\d+)人评价\s*\)</span>', book_html, re.DOTALL)
        rating_count = rating_count_match.group(1) if rating_count_match else '未找到评价人数'

        # 提取书籍简介
        quote_match = re.search(r'<span class="inq">(.*?)</span>', book_html)
        quote = quote_match.group(1) if quote_match else '无简介'

        # 提取书籍链接
        link_match = re.search(r'<a href="([^"]*)".*?title="[^"]*"', book_html)
        link = link_match.group(1) if link_match else '未找到链接'

        # 将书籍数据存储为字典
        book_data = {
            '排名': global_book_num,
            '书名': title,
            '出版信息': info,
            '评分': rating,
            '评价人数': rating_count,
            '简介': quote,
            '链接': link
        }
        books_data.append(book_data)

        print(f'第 {global_book_num} 本书: {title}')

    print(f'第 {page_num} 页解析完成，共解析 {len(books_data)} 本书')
    return books_data

def save_to_excel(books_data):
    print('\n开始保存数据到Excel...')
    # 创建Excel工作簿
    workbook = xlwt.Workbook(encoding='utf-8')
    worksheet = workbook.add_sheet('豆瓣读书Top250')

    # 设置表头
    headers = ['排名', '书名', '出版信息', '评分', '评价人数', '简介', '链接']
    for col, header in enumerate(headers):
        worksheet.write(0, col, header)

    # 写入书籍数据
    for row, book in enumerate(books_data, 1):
        worksheet.write(row, 0, book['排名'])
        worksheet.write(row, 1, book['书名'])
        worksheet.write(row, 2, book['出版信息'])
        worksheet.write(row, 3, book['评分'])
        worksheet.write(row, 4, book['评价人数'])
        worksheet.write(row, 5, book['简介'])
        worksheet.write(row, 6, book['链接'])

    # 保存Excel文件
    excel_filename = '豆瓣读书Top250.xls'
    workbook.save(excel_filename)
    print(f'数据已保存到 {excel_filename}')
    print(f'总共保存了 {len(books_data)} 本书的资料')

if __name__ == '__main__':
    main()